import TableExecutor from './TableExecutor';
import {open,isOpen,close,get,exec,transaction} from './SQLDriver.js';

const openpool = {};

/**
 * 数据库连接持有对象
 * @author xueyanjun
 */
class DataBase{
	constructor(name){
		this.name = name;
		this.tableExecutorPool = {};
		this.connectSuccess = false;
		this.trans = {
			// 开启事务
			begin:function(){
				return transaction.begin(this.name);
			},
			// 提交事务
			commit:function(){
				return transaction.commit(this.name);
			},
			// 回滚事务
			rollback:function(){
				return transaction.rollback(this.name);
			}
		}
	}
	/**
	 * 连接数据库
	 * @param {string} name 数据库名称
	 */
	static connect(name){
		let db = openpool[name];
		if(!db || !db.isconnect()){
			return open(name).then(()=>{
				db = db || new DataBase(name);
				db.connectSuccess = true;
				openpool[name] = db;
				return db;
			})
		}
		return Promise.resolve(db);
	}
	
	/**
	 * 断开数据库连接
	 * @param {string} name 数据库名称
	 */
	static disconnect(name){
		close(name).then(()=>{
			openpool[name].connectSuccess = false;
			delete openpool[name];
		});
	}
	
	/**
	 * 判断数据库是否成功连接
	 * @param {string} name 数据库名称
	 */
	static isconnect(name){
		const db = openpool[name];
		if(!db){
			return false;
		}
		if(!db.connectSuccess){
			db.connectSuccess = isOpen(db.name);
		}
		return db.connectSuccess;
	}
	
	/**
	 * 连接数据库
	 */
	connect(){
		return open(this.name).then(()=>{
			this.connectSuccess = true;
			openpool[this.name] = this;
			return this;
		})
	}
	
	/**
	 * 断开数据库
	 */
	disconnect(){
		close(this.name).then(()=>{
			this.connectSuccess = false;
			delete openpool[this.name];
		});
	}
	
	/**
	 * 判断数据库是否成功连接
	 */
	isconnect(){
		if(!this.connectSuccess){
			this.connectSuccess = isOpen(this.name);
		}
		return this.connectSuccess;
	}
	
	/**
	 * 创建表，如果表存在则会忽略
	 * @param {string} tableName 表名
	 * @param {Function} fn 表创建配置回调函数
	 */
	createTable(tableName,fn){
		return this.table(tableName).create(fn).then(()=>this);
	}
	
	/**
	 * 返回一个表操作对象
	 * @param {string} tableName 表名
	 */
	table(tableName){
		let executor = this.tableExecutorPool[tableName];
		if(!executor){
			this.tableExecutorPool[tableName] = executor = new TableExecutor(this.name,tableName);
		}
		return executor;
	}
}

DataBase.transaction = transaction;
DataBase.exec = exec;
DataBase.get = get;

export default DataBase;